#include<stdio.h>
typedef unsigned char U_CHAR;


typedef struct hashnode HASHNODE;

#define HASHSTEP(old, c) ((old << 2) + c)
#define MAKE_POS(v) (v & ~0x80000000) /* make number positive */

enum node_type {
	T_DEFINE = 1,	/* the `#define' keyword */
	T_INCLUDE,	/* the `#include' keyword */
	T_IFDEF,	/* the `#ifdef' keyword */
	T_IFNDEF,	/* the `#ifndef' keyword */
	T_IF,		/* the `#if' keyword */
	T_ELSE,	/* `#else' */
#if 0
	/* cpp can pass #pragma through unchanged.  */
	T_PRAGMA,	/* `#pragma' */
#endif
	T_ELIF,	/* `#else' */
	T_UNDEF,	/* `#undef' */
	T_LINE,	/* `#line' */
	T_ERROR,	/* `#error' */
	T_ENDIF,	/* `#endif' */
	T_SCCS,	/* `#sccs', used on system V.  */
	T_SPECLINE,	/* special symbol `__LINE__' */
	T_DATE,	/* `__DATE__' */
	T_FILE,	/* `__FILE__' */
	T_VERSION,	/* `__VERSION__' */
	T_TIME,	/* `__TIME__' */
	T_CONST,	/* Constant value, used by `__STDC__' */
	T_MACRO,	/* macro defined by `#define' */
	T_DISABLED,	/* macro temporarily turned off for rescan */
	T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
	T_UNUSED	/* Used for something not defined.  */
};

  struct reflist {
    struct reflist *next;
    char stringify;		/* nonzero if this arg was preceded by a
				   # operator. */
    char raw_before;		/* Nonzero if a ## operator before arg. */
    char raw_after;		/* Nonzero if a ## operator after arg. */
    int nchars;			/* Number of literal chars to copy before
				   this arg occurrence.  */
    int argno;			/* Number of arg to substitute (origin-0) */
  };

typedef struct definition DEFINITION;
struct definition {
  int nargs;
  int length;			/* length of expansion string */
  U_CHAR *expansion;
  struct reflist *pattern;
  /* Names of macro args, concatenated in reverse order
     with comma-space between them.
     The only use of this is that we warn on redefinition
     if this differs between the old and new definitions.  */
  U_CHAR *argnames;
};




/* different kinds of things that can appear in the value field
   of a hash node.  Actually, this may be useless now. */
union hashval {
  int ival;
  char *cpval;
  DEFINITION *defn;
};


struct hashnode {
  struct hashnode *next;	/* double links for easy deletion */
  struct hashnode *prev;
  struct hashnode **bucket_hdr;	/* also, a back pointer to this node's hash
				   chain is kept, in case the node is the head
				   of the chain and gets deleted. */
  enum node_type type;		/* type of special token */
  int length;			/* length of token, for quick comparison */
  U_CHAR *name;			/* the actual name */
  union hashval value;		/* pointer to expansion, or whatever */
};
int	hashf (register U_CHAR *name, register int len, int hashsize);
void bcopy (register unsigned char *b1, register unsigned char *b2, register int length);

DEFINITION *collect_expansion (U_CHAR *buf,U_CHAR *end,int nargs,struct arglist * arglist);
char *xcalloc (int number, int size);

/* The arglist structure is built by do_define to tell
   collect_definition where the argument names begin.  That
   is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
   would contain pointers to the strings x, y, and z.
   Collect_definition would then build a DEFINITION node,
   with reflist nodes pointing to the places x, y, and z had
   appeared.  So the arglist is just convenience data passed
   between these two routines.  It is not kept around after
   the current #define has been processed and entered into the
   hash table. */

struct arglist {
  struct arglist *next;
  U_CHAR *name;
  int length;
  int argno;
};

#define warning printf
#define error printf

char *xmalloc (int size);

void bzero (register char *b, register int length);
#define index strchr
#define rindex strrchr
